package main

import (
	"database/sql"
	"database/sql/driver"
	"fmt"
	"reflect"

	"github.com/go-playground/validator/v10"
)

type DbBackedUser struct {
	Name sql.NullString `validate:"required"`
	Age  sql.NullInt64  `validate:"required"`
}

var validate *validator.Validate

func main() {
	// 构建一个验证器
	validate = validator.New()
	// 注册所有sql.Null*类型使用特定的自定义验证器
	validate.RegisterCustomTypeFunc(ValidateValuer, sql.NullString{}, sql.NullBool{}, sql.NullFloat64{})
	// 绑定对象到验证器上
	x := DbBackedUser{Name: sql.NullString{String: "", Valid: true}, Age: sql.NullInt64{Int64: 0, Valid: true}}
	// 执行结构体验证
	err := validate.Struct(x)
	if err != nil {
		fmt.Printf("Err(s):\n%+v\n", err)
	}
}

// 实现validator.CustomTypeFunc接口
func ValidateValuer(field reflect.Value) interface{} {
	if valuer, ok := field.Interface().(driver.Valuer); ok {
		val, err := valuer.Value()
		if err == nil {
			return val
		}
	}
	return nil
}
